import i18n from '@/i18n/i18n'
import axios from '@/utils/request'
import Lockr from 'lockr'
import moment from 'moment'
import { Message } from 'element-ui'
import { debounce } from 'throttle-debounce'
import { crmCallInitTokenAPI, crmCallGetDZUrlAPI } from './call'
/**
 * 软乎 cmd
 * 2001：拨打电话
 * 2002：挂断电话
 * 2003：接通电话
 * 2004：通话结束
 * 2005：拨打或者挂断 成功
 * 2006：拨打或者 挂断失败
 */
class MyWs {
  webSokets
  callinTime
  timer
  callState
  devicename
  callInfo // 呼叫状态用于限制判断
  currentCCID // 当前使用的电话卡
  icallObj// 得助拨号盘控件对象
  $icall// 得助拨号盘常量对象
  open(f, error_func) {
    const callData = Lockr.get('wkCallData')
    // hisUse 0 是默认硬呼单卡 1 是软乎 2是硬呼多卡 3得助智能软乎
    if (callData && callData.hisUse == 1) {
      const token = axios.defaults.headers.common['Admin-Token']
      this.hisUse = 1
      const socketUrl = process.env.VUE_APP_CALL_SOCKET
      this.webSokets = new WebSocket(socketUrl + token) // ws://192.168.1.116:22150?token=
    } else if (callData && callData.hisUse == 2) {
      this.hisUse = 2
      this.webSokets = new WebSocket('ws://127.0.0.1:8555/api')
    } else {
      this.hisUse = 0
      this.webSokets = new WebSocket('ws://127.0.0.1:9501')
    }
    this.callinTime = '00:00:00'
    var that = this
    this.webSokets.onopen = () => {
      f()
      that.startTimePiece()
    }
    this.webSokets.onerror = (e) => {
      error_func(e)
    }
    this.webSokets.onclose = () => {
      that.close()
      clearInterval(this.timer) // 清除心跳包
    }
  }

  // hisUse 0 是默认硬呼 1 是软乎
  getHisUse() {
    const callData = Lockr.get('wkCallData')
    return callData ? callData.hisUse : 0
  }

  close() {
    this.webSokets.close()
    clearInterval(this.timer)
  }

  message(f) {
    this.webSokets.onmessage = (e) => {
      const data = JSON.parse(e.data)
      const callData = Lockr.get('wkCallData')
      // hisUse 0 是默认单卡硬呼 1 是软乎 2是多卡硬呼
      if (callData && callData.hisUse == 1) {
        if (data.cmd === 2004 || data.cmd === 2006) {
          this.callState = 1
        } else if (data.cmd === 2011 && data.status === 'IDLE') {
          this.callState = 1
        } else {
          this.callState = 2
        }
      } else if (callData && callData.hisUse == 2) {
        if (data.type == 'RealTimeState') {
          if (
            data.dynamicdata.realtimestate === 'hangup' ||
            data.dynamicdata.realtimestate === 'idle'
          ) {
            this.callState = 1
          } else if (
            data.dynamicdata.realtimestate === 'outgoing' ||
            data.dynamicdata.realtimestate === 'ringback' ||
            data.dynamicdata.realtimestate === 'incoming' ||
            data.dynamicdata.realtimestate === 'outconnected' ||
            data.dynamicdata.realtimestate === 'inconnected'
          ) {
            this.callState = 2
          }
        } else if (data.type == 'CallRecord') {
          this.callState = 1
        } else if (data.type == 'DeviceConnectedState') {
          this.callState = 2
        } else if (
          data.type == 'CommandResponse' &&
          data.dynamicdata &&
          data.dynamicdata.state === 'CALL_STATE_IDLE'
        ) {
          this.callState = 1
        }
      } else {
        if (data.event === 'CallState') {
          this.callState = data.data.callState
        } else if (
          data.event === 'OutGoing' ||
          data.event === 'RingBack' ||
          data.event === 'InComing' ||
          data.event === 'Answer'
        ) {
          this.callState = 2
        } else if (data.event === 'HangUp' || data.event === 'Idle') {
          this.callState = 1
        }
      }

      if (callData && callData.hisUse == 2) {
        if (data.type == 'InstructionTrace') {
          f(data)
        } else if (data.type == 'RealTimeState') {
          f(data)
          const limitRealtimestate = data.dynamicdata.realtimestate
          this.callInfo = this.callInfo || {}
          if (limitRealtimestate === 'outgoing') {
            // 设备呼出
            this.callInfo = {
              isOut: true,
              connected: false,
              isHangup: false
            }
          } else if (limitRealtimestate === 'incoming') {
            // 来电呼入
            this.callInfo = {
              isOut: false,
              connected: false,
              isHangup: false
            }
          } else if (
            limitRealtimestate === 'outconnected' ||
            limitRealtimestate === 'inconnected'
          ) {
            // 呼出接通 呼入接通
            this.callInfo.connected = true
          } else if (limitRealtimestate === 'hangup') {
            // 挂断电话
            this.callInfo.isHangup = true
          }

          // 限制逻辑 呼出 接通了 并且 挂断时 执行
          if (
            this.callInfo.isOut &&
            this.callInfo.connected &&
            this.callInfo.isHangup
          ) {
            setTimeout(() => {
              this.OnHandleLimit()
            }, 2000)
          }
        } else {
          if (data.data != null && data.data.invoke_command) {
            if (
              data.data.invoke_command.toLowerCase() ==
              'getconnectedstate_multi'
            ) {
              // 获取已连接设备
              // 解析已连接设备序列号
              const devicelist = data.dynamicdata.devicelist
              if (devicelist != '') {
                this.devicename = devicelist.split(',')[0]
                this.GetCallState()
                this.OnGetCCID() // 获得电话卡标识
              }
            } else if (
              data.data.invoke_command.toLowerCase() == 'getccid_multi'
            ) {
              // 获取ccid电话卡标识
              this.currentCCID = data.dynamicdata.ccid
            }
          }

          // 处理换卡结果
          if (data.type === 'CommandResponse') {
            const dataResult = data.data || {}
            if (
              dataResult.invoke_command &&
              dataResult.invoke_command.toLowerCase() == 'cbswitchnext_multi'
            ) {
              if (dataResult.state) {
                Message({
                  message: i18n.t(
                    'callCenter.callWebSokets.03b7763ea1f29343aae4b0297aca6d0b'
                  ),
                  type: 'success'
                })
              } else {
                Message({
                  message: i18n.t(
                    'callCenter.callWebSokets.f7f5d9a57c06e0d21e6d72e770a2c17d'
                  ),
                  type: 'error'
                })
              }
            }
          }
          f(data)
        }
      } else {
        f(data)
      }
    }
  }

  send(data) {
    this.webSokets.send(JSON.stringify(data))
  }

  // 清除计时器
  clearWebSoketsInterval() {
    clearInterval(this.timer)
  }
  // 重启计时器,保持连接
  // 计数器
  startTimePiece() {
    this.timer = setInterval(() => {
      const callData = Lockr.get('wkCallData')
      // hisUse 0 是默认硬呼单卡 1 是软乎 2是硬呼多卡
      if (callData && callData.hisUse == 1) {
        this.send({
          cmd: 1000
        })
      } else if (callData && callData.hisUse == 2) {
        this.send('HeartBeatData')
      } else {
        this.send({
          event: 'HeartBeat'
        })
      }
    }, 10000)
  }
  addFix(num, length) {
    return ('' + num).length < length
      ? (new Array(length + 1).join('0') + num).slice(-length)
      : '' + num
  }
  // 拨号
  OnDailout(phoneNumber) {
    if (this.callState === 1) {
      const callData = Lockr.get('wkCallData')
      // hisUse 0 是默认硬呼单卡 1 是软乎 2是硬呼多卡 3得助智能软乎
      if (callData && callData.hisUse == 1) {
        this.send({
          cmd: 2001, // 2001：拨打电话
          phone: String(phoneNumber)
        })
      } else if (callData && callData.hisUse == 2) {
        this.send({
          command: 'Dial_Multi',
          arguments: { phone: String(phoneNumber), devicename: this.devicename }
        })
      } else {
        this.send({
          event: 'Dial',
          number: String(phoneNumber)
        })
        return true
      }
    } else {
      return false
    }
  }
  // 判断话机状态是否能拨打
  CheckCallState() {
    const result = this.callState === 1
    const callData = Lockr.get('wkCallData')
    if (callData && callData.hisUse == 3) {
      if (!result) {
        Message({
          message: '请检查麦克风权限重新刷新加载呼叫中心',
          duration: 1500,
          type: 'error'
        })
      }
    } else {
      if (!result) {
        Message({
          message: i18n.t(
            'callCenter.callWebSokets.024b1d25bc13bc3d38ab5bf4794d17dc'
          ),
          duration: 1500,
          type: 'error'
        })
      }
    }

    return result
  }
  // 接听
  OnAnswer() {
    const callData = Lockr.get('wkCallData')
    // hisUse 0 是默认硬呼单卡 1 是软乎 2是硬呼多卡
    if (callData && callData.hisUse == 1) {
      // 暂无主动接通，只能通过软乎接通
    } else if (callData && callData.hisUse == 2) {
      this.send({
        command: 'Answer_Multi',
        arguments: { devicename: this.devicename }
      })
    } else {
      this.send({
        event: 'Answer'
      })
    }
  }
  // 挂断
  OnHungUp() {
    const callData = Lockr.get('wkCallData')
    // hisUse 0 是默认硬呼单卡 1 是软乎 2是硬呼多卡
    if (callData && callData.hisUse == 1) {
      this.send({
        cmd: 2002 // 2002：挂断电话
      })
    } else if (callData && callData.hisUse == 2) {
      this.send({
        command: 'HangUp_Multi',
        arguments: { devicename: this.devicename }
      })
    } else {
      this.send({
        event: 'HangUp'
      })
    }
  }
  // 获取通话状态
  OnGetCallState() {
    const callData = Lockr.get('wkCallData')
    // hisUse 0 是默认单卡硬呼 1 是软乎 2是多卡硬呼
    if (callData && callData.hisUse == 1) {
      this.send({
        cmd: 2010 // 主动获取话机状态：2010
      })
    } else if (callData && callData.hisUse == 2) {
      this.send({
        command: 'OpenDevice_Multi'
      })
      setTimeout(this.OnGetConnectedState(), 3000)
    } else {
      this.send({
        event: 'GetCallState'
      })
    }
  }
  // 获取通话状态
  GetCallState() {
    this.send({
      command: 'GetCallState_Multi',
      arguments: { devicename: this.devicename }
    })
  }
  // 上传
  OnUploadFile(url, session_id) {
    const callData = Lockr.get('wkCallData')
    // hisUse 0 是默认单卡硬呼 1 是软乎 2是多卡硬呼
    if (callData && callData.hisUse == 2) {
      this.send({
        command: 'UploadFile',
        arguments: { url: url, file: session_id }
      })
    } else {
      this.send({
        event: 'UploadRecord',
        url,
        session_id
      })
    }
  }

  /**
   * 多卡逻辑
   *
   */
  // 获取设备连接状态
  OnGetConnectedState() {
    this.send({
      command: 'GetConnectedState_Multi'
    })
    // 隐藏客户端客户端菜单，设置空则不隐藏   //主页0，号码1，常规设置2，设备管理3，系统设置4，AI设置5，联系人6，短信管理7通话详情8，报表9，自助修复10，帮助11
    this.send({ command: 'hidemenu', arguments: { content: '' }})
  }

  // 获取ccid
  OnGetCCID() {
    this.send({
      command: 'GetCCID_Multi',
      arguments: { devicename: this.devicename }
    })
  }

  // 换下张卡
  OnSwitchNext() {
    this.send({
      command: 'CBSwitchNext_Multi',
      arguments: { devicename: this.devicename }
    })
  }

  // 执行限制换卡逻辑
  OnHandleLimit = debounce(2000, false, () => {
    const limitSet = Lockr.get('wkCallLimitSet')
    if (limitSet && limitSet.open && this.currentCCID) {
      const limitNum = limitSet.num
      const timeKey = moment().format('YYYY-MM-DD')
      let limitData = Lockr.get('wkCallLimitData')

      const defalutCCIDData = {}
      defalutCCIDData[this.currentCCID] = 1

      if (limitData) {
        const todyData = limitData[timeKey]
        if (todyData && todyData.hasOwnProperty(this.currentCCID)) {
          todyData[this.currentCCID]++
        } else {
          limitData = {}
          limitData[timeKey] = defalutCCIDData
        }
      } else {
        limitData = {}
        limitData[timeKey] = defalutCCIDData
      }

      console.log('wkCallLimitData---', limitData)
      Lockr.set('wkCallLimitData', limitData)

      // 单卡数量大于等于设置 进行切换操作
      if (limitData) {
        const currentNum = limitData[timeKey][this.currentCCID]
        if (currentNum >= limitNum) {
          this.OnSwitchNext()
        }
      }
    }
  })

  // 开始录音
  OnStartRecord() {
    this.send({
      command: 'StartRecord_Multi',
      arguments: { devicename: this.devicename }
    })
  }
  // 结束录音
  OnStopRecord() {
    this.send({
      command: 'StopRecord_Multi',
      arguments: { devicename: this.devicename, isconverttomp3: 'true' }
    })
  }
  /**
   * -----------------------------------得助智能呼叫中心-----------------------------------
   *
   */
  /**
* 开始
*/
  start(f) {
    crmCallGetDZUrlAPI().then((res) => {
      const dezhuDomain = res.data || 'https://wukong.dezhuyun.com'
      // 根据域名引入拨号盘sdk
      var ele = document.createElement('script')
      ele.setAttribute('type', 'text/javascript')
      ele.setAttribute('src', dezhuDomain + '/dzfront/icall/lib/icall.js')
      ele.onload = () => {
        this.init(dezhuDomain, f)
      }
      document.body.appendChild(ele)
    }).catch(() => {})
  }

  /**
* 初始化拨号盘
*/
  init(server, f) {
  // const that = this
  // eslint-disable-next-line no-undef
    var obj = new Icall('testICall', {
      option: {
        server: server,
        logName: '日志',
        className: 'customClass',
        isShowSignOutButton: false
      },
      notify: {
        handle: (toastInfo) => {
          // console.log('-----------------------------------------')
          // console.log(toastInfo)
          // console.log(toastInfo.type)
          switch (toastInfo.type) {
          // 提示
            case this.$icall.ToastType.Info:
            // TODO

              break
          }
        // f(toastInfo)
        // recordJsonData({ message: 'notify.handle通知回调', data: { toastInfo }})
        }
      },
      event: {

        // 坐席状态改变
        onUserStatusChange: (userStatus, label) => {
          if (!this.$icall) return
          // if (userStatus !== that.$icall.UserStatus.Offline) {
          //   hideDom('login')
          //   showDom('handle')
          // } else {
          //   hideDom('handle')
          //   showDom('login')
          // }
          if (['READY_MANUAL_CALLS', 'READY'].includes(userStatus)) {
            this.callState = 1
          } else {
            this.callState = 2
          }
          console.log('坐席状态改变坐席状态改变')
          console.log(userStatus)
          f('onUserStatusChange', userStatus)
        // TODO
        // recordJsonData({ message: 'onUserStatusChange事件返回', data: { userStatus, label }})
        },
        onLoginInfoChange: (loginInfo) => {
        // TODO
          console.log('登录信息')
          console.log(loginInfo)
          f('onLoginInfoChange', loginInfo)
        },
        onUserInfoChange: (userInfo) => {
        // TODO
          console.log('用户信息')
          console.log(userInfo)
          f('onLoginInfoChange', userInfo)
        },
        onLoginFail: (error) => {
        // TODO
          console.log('签入失败')
          console.log(error)
          f('onLoginFail', error)
        },
        // onCallTypeChange: (callType) => {
        //   switch (callType) {
        //   // 呼入
        //     case this.iCall.$Call.CallType.In:
        //     // TODO
        //       break
        //       // 呼出
        //     case this.$Call.CallType.Out:
        //     // TODO
        //       break
        //   }
        // },
        onCallStatusChange: function(callStatus) {
          console.log(callStatus)
          f('onCallStatusChange', callStatus)
        // switch (callStatus) {
        //   // 等待接听
        //   case this.$Call.CallStatus.InWaitingForAnswer:
        //     // TODO
        //     break
        //   // 呼入通话中
        //   case this.$Call.CallStatus.InActive:
        //     // TODO
        //     break
        // }
        },
        onCallDataChange: (callData) => {
        // TODO
        // {
        //   'agentCallUUID':"513ab762-fd5f-431a-9219-4353136943a0",
        //   'callId':"606aa6db-b471-42b0-9097-fdaad0644b31"
        // }
          console.log('呼叫数据改变')
          console.log(callData)
          f('onCallDataChange', callData)
        },
        onWillHangup: (callStatus, isAutoAnswer) => {
          console.log('将要主动挂断')
          console.log(callStatus)
          console.log(isAutoAnswer)
          return new Promise((resolve, reject) => {
          // TODO
            resolve(true)
          })
        },
        onFinishedAcw: (acwDuration) => {
        // TODO
          console.log('通话结束')
          console.log(acwDuration)
        },
        onTransferOtherSuccess: (number, type) => {
        // TODO
          console.log('转接外线成功')
          console.log(number)
          console.log(type)
        },
        onListenStart: (monitorData) => {
        // TODO
          console.log('监听开始')
          console.log(monitorData)
        },
        onListenEnd: (monitorData) => {
        // TODO
          console.log('监听结束')
          console.log(monitorData)
        },
        onJoinStart: (monitorData) => {
        // TODO
          console.log('插入开始')
          console.log(monitorData)
        },
        onJoinEnd: (monitorData) => {
        // TODO
          console.log('插入结束')
          console.log(monitorData)
        },
        onOutboundNumberChange: (outboundNumber) => {
        // TODO
        // TODO
          console.log('外显号码改变')
          console.log(outboundNumber)
        }
      }

    }, () => {
      this.icallObj = obj.ref
      this.$icall = obj.$Call
      this.login()
    })
  }

  /**
* 登录
*/
  login() {
    crmCallInitTokenAPI().then((res) => {
      this.icallObj && this.icallObj.signIn(res.data)
    })
    //   var input = document.getElementsByClassName('token')[0]
    //   if (input.value) {
    // const dezhuToken = 'UserBearer5076a42aec4c301de2038ab90b3cf9db0bff595fa93a817cb35df8abc56102dc1bc94774'
    // console.log('denglul')
    // console.log(this)
    // this.icallObj && this.icallObj.signIn(dezhuToken)
    //   }
  }

  /**
* 退出
*/
  logout() {
    this.icallObj && this.icallObj.signOut()
  }

  /**
* 改变坐席状态
* @param {*} status
*/
  changeUserStatus(status) {
    switch (status) {
      case 'online':
        this.icallObj && this.icallObj.setUserStatus(this.$icall.RequestUserStatus.Online)
        break
      case 'out':
        this.icallObj && this.icallObj.setUserStatus(this.$icall.RequestUserStatus.Out)
        break
      case 'rest':
        this.icallObj && this.icallObj.setUserStatus(this.$icall.RequestUserStatus.Away)
        break
    }
    // this.recordLog({ logType: this.$icall.LogType.Info, message: '切换坐席状态', content: status })
  }

  /**
* 显示拨号盘
*/
  showPhone() {
    this.icallObj && this.icallObj.showPhone()
  }

  /**
* 隐藏拨号盘
*/
  hidePhone() {
    this.icallObj && this.icallObj.hidePhone()
  }

  /**
* 呼叫
*/
  call(phoneNumber) {
    if (phoneNumber && /^[0-9]+$/.test(phoneNumber)) {
    // this.recordLog({ logType: this.$icall.LogType.Info, message: '呼叫', content: input.value })
      this.icallObj && this.icallObj.call(phoneNumber)
      return
    }
    alert('请输入正确手机号！')
  }

  /**
* 转接外部号码
*/
  transferOut() {
    var input = document.getElementsByClassName('transfer-out')[0]
    if (input.value && /^[0-9]+$/.test(input.value)) {
      this.recordLog({ logType: this.$icall.LogType.Info, message: '转接外部号码', content: input.value })
      this.icallObj && this.icallObj.transferOther({ number: input.value })
      return
    }
    alert('请输入正确手机号！')
  }

  /**
* 记录日志
*/
  recordLog(log) {
    this.icallObj && this.icallObj.recordLog(log)
  }

  /**
* 清空日志
*/
  clearLog() {
    this.icallObj && this.icallObj.clearLog()
  }

  /**
* 下载日志
*/
  downloadLog() {
    this.icallObj && this.icallObj.downloadLog()
  }

  /**
* 接听
*/
  answer() {
    this.icallObj && this.icallObj.answer()
  }

  /**
* 挂断
*/
  hangup() {
    this.icallObj && this.icallObj.hangup()
  }

  /**
* 暂停
*/
  hold() {
    this.icallObj && this.icallObj.hold()
  }

  /**
* 取消暂停
*/
  unHold() {
    this.icallObj && this.icallObj.unHold()
  }

  /**
* 静音
*/
  mute() {
    this.icallObj && this.icallObj.mute()
  }

  /**
* 取消静音
*/
  unMute() {
    this.icallObj && this.icallObj.unMute()
  }
}

export default new MyWs()
